/**
	Copyright (c) 2010 ATTi 
	All rights reserved.
	Author: Michael Shu
	Date: 2/25/2010
*/

trigger CaseSubCaseCreateAndRollUpSummary on Case (before insert, before update, before delete, after delete, after insert, after update) {
	   if(trigger.isBefore){
	   	    List<Case> incidentsInsert = new List<Case>();
	   	    List<Case> incidentsUpdate = new List<Case>();
	   	    List<Case> stubsInsert = new List<Case>();
	   	    List<Case> stubsUpdate = new List<Case>();
	   	    List<Case> allIOGcases = new List<Case>();
	   	    if(trigger.isInsert){
	   	    	for(Case c: trigger.new){
	   	    		if(c.RecordTypeId == CaseIOGClass.IOGIncidentRecordTypeID){
	   	    			incidentsInsert.add(c);
	   	    		}	 
	   	    		if(CaseIOGClass.STUBRecordTypeIDs.contains(c.RecordTypeId)){
	   	    			stubsInsert.add(c);
	   	    		}
	   	    		if(CaseIOGClass.AllIOGRecordTypeIDs.contains(c.RecordTypeId)){
	   	    			allIOGcases.add(c);
	   	    		}	    		
	   	    	}
	   	    }else if(trigger.isUpdate){
	   	    	for(Case c: trigger.new){
	   	    		Case oldCase = trigger.oldMap.get(c.Id);
	   	    		if(c.RecordTypeId == CaseIOGClass.IOGIncidentRecordTypeID){
	   	    			incidentsUpdate.add(c);
	   	    		}
	   	    		if(CaseIOGClass.STUBRecordTypeIDs.contains(c.RecordTypeId)){
	   	    			stubsUpdate.add(c);
	   	    		}
	   	    		if(CaseIOGClass.AllIOGRecordTypeIDs.contains(c.RecordTypeId)){
	   	    			allIOGcases.add(c);
	   	    		}	   	    		
	   	    	}
	   	    }
	   	    CaseIOGClass.setIncidentCasesOnlyInsert(incidentsInsert);	
	   	    CaseIOGClass.setIncidentCasesOnlyUpdate(incidentsUpdate, trigger.oldMap);
	   	    CaseIOGClass.setStubCasesInsert(stubsInsert);	   	    	
	   	    CaseIOGClass.setStubCasesUpdate(stubsUpdate, trigger.oldMap);	   	    		   	    	
	   	    CaseIOGClass.setAllIOGCases(allIOGcases);
	   	    CaseIOGClass.checkAllValidationRules(allIOGcases, trigger.oldMap);
		}else if(trigger.isAfter){				
			Set<ID> incidentAddNewStubIds_CRF_Package = new Set<ID>();
			Set<ID> incidentAddNewStubIds_Affected_Products = new Set<ID>();
			Set<ID> incidentOwnerUpdateIds = new Set<ID>();
			Set<ID> incidentAccountContactOriginAMUpdateIds = new Set<ID>();
			Set<ID> incidentEscalateIds = new Set<ID>();
			Set<ID> parentCaseIds = new Set<ID>();
			Set<ID> irChangeCaseIds = new Set<ID>();
			Set<ID> statusChangeCaseIds = new Set<ID>();
			
			if(trigger.isInsert){
				for(Case c : trigger.new){	
					if(c.RecordTypeId == CaseIOGClass.IOGIncidentRecordTypeID && c.CRF_PACKAGE__c != null){
						incidentAddNewStubIds_CRF_Package.add(c.Id);
					}
					if(c.RecordTypeId == CaseIOGClass.IOGIncidentRecordTypeID && c.CSS_ProductFamily__c != null 
					  && c.CSS_CRF_RequestType__c != null && CaseIOGClass.RequestTypes.contains(c.CSS_CRF_RequestType__c)){
						incidentAddNewStubIds_Affected_Products.add(c.Id);
					}
					if(CaseIOGClass.STUBRecordTypeIDs.contains(c.RecordTypeId)){
						parentCaseIds.add(c.ParentId);
					}
				}
			}else if(trigger.isUpdate){
				List<Case> fiCases = new List<Case>(); // updated by plo, 05/28/12 AD-29807 
				for(Case c : trigger.new){
					Case oldCase = trigger.oldMap.get(c.Id);
					String tPrefix = String.Valueof(c.OwnerId).subString(0,3);	
					if(c.RecordTypeId == CaseIOGClass.IOGIncidentRecordTypeID){
						if(!c.isClosed && c.CRF_PACKAGE__c != oldCase.CRF_PACKAGE__c && c.CRF_PACKAGE__c != null){
							incidentAddNewStubIds_CRF_Package.add(c.Id);
						}
						if(!c.isClosed && (c.CSS_ProductFamily__c != oldCase.CSS_ProductFamily__c || c.CSS_CRF_RequestType__c != oldCase.CSS_CRF_RequestType__c)
						   && c.CSS_ProductFamily__c != null && c.CSS_CRF_RequestType__c != null && CaseIOGClass.RequestTypes.contains(c.CSS_CRF_RequestType__c)){
							incidentAddNewStubIds_Affected_Products.add(c.Id);
						}
						if(c.OwnerId != oldCase.OwnerId){
							incidentOwnerUpdateIds.add(c.Id);
						}
						if(c.Status != oldCase.Status && c.Status == CaseIOGClass.ESCALATED && c.CSS_InitialEscalationDateTime__c == null){
							incidentEscalateIds.add(c.Id);
						}
						if(c.AccountId != oldCase.AccountId || c.ContactId != oldCase.ContactId || c.Account_Manager__c != oldCase.Account_Manager__c || c.Origin != oldCase.Origin){
							incidentAccountContactOriginAMUpdateIds.add(c.Id);
						}
					}
					if(CaseIOGClass.STUBRecordTypeIDs.contains(c.RecordTypeId)){
						if(c.Status != oldCase.Status || c.IR_Priority__c != oldCase.IR_Priority__c || c.RecordTypeId != oldCase.RecordTypeId 
						                              || c.Product_Family__c != oldCase.Product_Family__c){
							parentCaseIds.add(c.ParentId);
						}
						if(c.ParentId != oldCase.ParentId){ // only for system admin
							parentCaseIds.add(c.ParentId);
							parentCaseIds.add(oldCase.ParentId);
						}
					}
					if(CaseIOGClass.AllIOGRecordTypeIDs.contains(c.RecordTypeId)){
						if(!c.isClosed && tPrefix == CaseIOGClass.User_Prefix && c.OwnerId != UserInfo.getUserId()){
							if(c.IR_Priority__c != oldCase.IR_Priority__c){
								irChangeCaseIds.add(c.Id);
							}
							if(c.Status != oldCase.Status){
								statusChangeCaseIds.add(c.Id);
							}
						 }
					}
				}	
			}else if(trigger.isDelete){
				for(Case c : trigger.old){
					if(CaseIOGClass.STUBRecordTypeIDs.contains(c.RecordTypeId)){
						parentCaseIds.add(c.ParentId);
					}	
				}
			}		
			CaseIOGClass.insertNewSubCasesFromCRFPackage(incidentAddNewStubIds_CRF_Package);
			CaseIOGClass.insertNewSubCasesFromAffectedProducts(incidentAddNewStubIds_Affected_Products, trigger.newMap); 
			CaseIOGClass.updateParentIncidentCases(parentCaseIds); 
			CaseIOGClass.updateStubsFromParentCases(incidentOwnerUpdateIds, incidentAccountContactOriginAMUpdateIds, incidentEscalateIds);
			CaseIOGClass.sendEmailtoCaseOwnerforEvents(irChangeCaseIds, statusChangeCaseIds);
		}
}